/**
 * Copyright 2012 Alfredo "Rainbowbreeze" Morresi
 * 
 * This file is part of Eureka! project.
 * 
 * Eureka! is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * Eureka! is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with Eureka!. If not, see http://www.gnu.org/licenses/.
 */
package it.rainbowbreeze.eureka.data;

import java.util.ArrayList;
import java.util.List;

import com.google.android.maps.GeoPoint;

import it.rainbowbreeze.eureka.common.LogFacility;
import it.rainbowbreeze.eureka.domain.QualityDataPoint;
import it.rainbowbreeze.libs.data.RainbowBaseContentProviderDao;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;

/**
 * 
 * @author Alfredo "Rainbowbreeze" Morresi
 *
 */
public class QualityDataPointDao extends RainbowBaseContentProviderDao<QualityDataPoint> {
    // ------------------------------------------ Private Fields
    private static final String LOG_HASH = QualityDataPointDao.class.getSimpleName();
    
    private final LogFacility mLogFacility;

    
    // -------------------------------------------- Constructors
    public QualityDataPointDao(LogFacility logFacility) {
        super(logFacility);
        mLogFacility = logFacility;
    }


    // --------------------------------------- Public Properties
    
    /**
     * Returns point in a specific range and for a specific radius
     * @param center
     * @param radius
     * @return
     */
    public List<QualityDataPoint> getPointsAround(
            Context context,
            int minLatitude,
            int minLongitude,
            int maxLatitude,
            int maxLongitude,
            int minReferringRadius,
            int maxReferringRadius,
            long minReadingTime) {
        
        StringBuilder queryBuilder = new StringBuilder();
        queryBuilder
                .append(EurekaContract.QualityPoint.LATITUDE)
                .append(" >= ")
                .append(minLatitude)
                .append(" & " )
                .append(EurekaContract.QualityPoint.LATITUDE)
                .append(" <= ")
                .append(maxLatitude)
                .append(" & " )
                .append(EurekaContract.QualityPoint.LONGITUDE)
                .append(" >= ")
                .append(minLongitude)
                .append(" & " )
                .append(EurekaContract.QualityPoint.LONGITUDE)
                .append(" <= ")
                .append(maxLongitude)
                .append(" & " )
                .append(EurekaContract.QualityPoint.RADIUS)
                .append(" >= ")
                .append(minReferringRadius)
                .append(" & " )
                .append(EurekaContract.QualityPoint.RADIUS)
                .append(" <= ")
                .append(maxReferringRadius)
                .append(" & " )
                .append(EurekaContract.QualityPoint.READING_TIMESTAMP)
                .append(" >= ")
                .append(minReadingTime);
        
        Cursor cursor = performSmartQuery(
                context,
                getBaseUri(),
                null,
                queryBuilder.toString(),
                null,
                null);
        
        List<QualityDataPoint> points = new ArrayList<QualityDataPoint>();
        if (null != cursor) {
            while (cursor.moveToNext()) {
                QualityDataPoint point = toItem(cursor);
                points.add(point);
            }
        }
        mLogFacility.v(LOG_HASH, "Found " + points.size() + " points around the selected coordinates");
        return points;
    }

    // ------------------------------------------ Public Methods
    /* (non-Javadoc)
     * @see it.rainbowbreeze.libs.data.RainbowBaseContentProviderDao#toContentProviderValues(it.rainbowbreeze.libs.data.RainbowSettableId)
     */
    @Override
    public ContentValues toContentProviderValues(QualityDataPoint item) {
        ContentValues values = new ContentValues();
        values.put(EurekaContract.QualityPoint.ACQUISITION_TIMESTAMP, item.getAcquisitionTimestamp());
        values.put(EurekaContract.QualityPoint.CATEGORYID, item.getCategoryId());
        values.put(EurekaContract.QualityPoint.LATITUDE, item.getLatitude());
        values.put(EurekaContract.QualityPoint.LONGITUDE, item.getLongitude());
        values.put(EurekaContract.QualityPoint.MEASURE_ID, item.getMeasureId());
        values.put(EurekaContract.QualityPoint.RADIUS, item.getRadius());
        values.put(EurekaContract.QualityPoint.READING_TIMESTAMP, item.getReadingTimestamp());
        values.put(EurekaContract.QualityPoint.REFERRING_RADIUS, item.getReferringRadius());
        values.put(EurekaContract.QualityPoint.VALUE, item.getValue());
        values.put(EurekaContract.QualityPoint.SCORE, item.getScore());
        return values;
    }


    /* (non-Javadoc)
     * @see it.rainbowbreeze.libs.data.RainbowBaseContentProviderDao#toItem(android.database.Cursor)
     */
    @Override
    public QualityDataPoint toItem(Cursor cursor) {
        QualityDataPoint item = new QualityDataPoint();
        item.setId(cursor.getLong(cursor.getColumnIndex(EurekaContract.QualityPoint._ID)));        
        item.setAcquisitionTimestamp(cursor.getLong(cursor.getColumnIndex(EurekaContract.QualityPoint.ACQUISITION_TIMESTAMP)));
        item.setCategoryId(cursor.getLong(cursor.getColumnIndex(EurekaContract.QualityPoint.CATEGORYID)));        
        item.setLatitude(cursor.getInt(cursor.getColumnIndex(EurekaContract.QualityPoint.LATITUDE)));        
        item.setLongitude(cursor.getInt(cursor.getColumnIndex(EurekaContract.QualityPoint.LONGITUDE)));        
        item.setMeasureId(cursor.getLong(cursor.getColumnIndex(EurekaContract.QualityPoint.MEASURE_ID)));
        item.setRadius(cursor.getInt(cursor.getColumnIndex(EurekaContract.QualityPoint.RADIUS)));        
        item.setReadingTimestamp(cursor.getLong(cursor.getColumnIndex(EurekaContract.QualityPoint.READING_TIMESTAMP)));
        item.setReferringRadius(cursor.getInt(cursor.getColumnIndex(EurekaContract.QualityPoint.REFERRING_RADIUS)));
        item.setScore(cursor.getInt(cursor.getColumnIndex(EurekaContract.QualityPoint.SCORE)));        
        item.setValue(cursor.getDouble(cursor.getColumnIndex(EurekaContract.QualityPoint.VALUE)));
        return item;
    }


    // ----------------------------------------- Private Methods
    /* (non-Javadoc)
     * @see it.rainbowbreeze.libs.data.RainbowBaseContentProviderDao#getLogHash()
     */
    @Override
    protected String getLogHash() {
        return LOG_HASH;
    }

    /* (non-Javadoc)
     * @see it.rainbowbreeze.libs.data.RainbowBaseContentProviderDao#getBaseUri()
     */
    @Override
    protected Uri getBaseUri() {
        return EurekaContract.QualityPoint.CONTENT_URI;
    }

    // ----------------------------------------- Private Classes
}
